// 实现这个项目的构建任务
const {src, dest, series, parallel, watch} = require('gulp');
const del = require('del');
const browserSync = require('browser-sync');
const bs = browserSync.create();

const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();

let config = {
  build: {
    public: 'public',
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    paths: {
      styles: 'assets/styles/*.scss',
      scripts: 'assets/scripts/*.js',
      pages: '**/*.html',
      images: 'assets/images/**',
      fonts: 'assets/fonts/**'
    }
  }
}  

// 清空dist, temp
// 先yarn add del --dev
const clean = () => {
  return del([config.build.dist, config.build.temp]);
}

// 样式编译并拷贝到temp dev
// 先yarn add gulp-sass --dev
const style = () => {
  return src(config.build.paths.styles, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.sass({outputStyle: 'expended'}))
    .pipe(dest(config.build.temp))
}

// 脚本编辑并拷贝到temp dev
// 先yarn add gulp-babel --dev
// yarn add @babel/core @babel/preset-env
const script = () => {
  return src(config.build.paths.scripts, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.babel({presets: [require('@babel/preset-env')]}))
    .pipe(dest(config.build.temp))
}

// html文件编译并拷贝到temp dev
// 先yarn add gulp-swig --dev
const page = () => {
  return src(config.build.paths.pages, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.swig({data: config.data}))
    .pipe(dest(config.build.temp))
}

// 图片文件压缩并拷贝到dist build
// 先yarn add gulp-imagemin --dev
const image = () => {
  return src(config.build.paths.images, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
}

// 字体文件压缩并拷贝到dist build
// 先yarn add gulp-imagemin --dev
const fonts = () => {
  return src(config.build.paths.fonts, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
}

// public文件复制并拷贝到dist build
const public = () => {
  return src('**', {base: config.build.public, cwd: config.build.public})
    .pipe(dest(config.build.dist));
}

// useref文件引用处理，压缩文件, 丑化代码，并拷贝到dist build
// 先yarn add gulp-useref --dev
const useref = () => {
  return src(config.build.paths.pages, {base: config.build.temp, cwd: config.build.temp})
    .pipe(plugins.useref({searchPath:[config.build.temp, '.']}))
    // 压缩html, css, JavaScript
    // yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev
    // yarn add gulp-if --dev
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest(config.build.dist))
}

// serve 自动监听文件修改
const serve = () => {
  // watch监听src下原始文件的改动，改动之后触发对应文件的编译任务
  // 编译任务执行之后，temp目录下文件也就变化了，被server根据files中的路径监听到，server重新展示
  watch(config.build.paths.styles, {cwd: config.build.src}, style);
  watch(config.build.paths.scripts, {cwd: config.build.src}, script);
  watch(config.build.paths.pages, {cwd: config.build.src}, page);
  watch([
    config.build.paths.images,
    config.build.paths.fonts
  ], {cwd: config.build.src}, bs.reload);
  watch('**', {cwd: config.build.public}, bs.reload);
  bs.init({
    notify: false,
    port: 2080,
    files: ['dist/**','temp/**'], // 指定文件改动监听路径
    server:{
      // 启动server时找文件的路径，及先后, 只有启动时用
      baseDir: [config.build.temp, config.build.src, config.build.public],
      routes: {
        '/node_modules':'node_modules'
      }
    }
  })
}

// 编译任务
const complie = parallel(style, script, page);

// 资源任务
const resource = parallel(image, fonts, public);

// 构建任务
const build = series(
  clean,
  parallel(
    series(complie, useref),
    resource
  )
)

// 开发任务
const dev = series(complie, serve);

module.exports = {
  clean,
  build,
  dev
}